﻿using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.U2D;
/// <summary>
/// 资源回应
/// </summary>
public abstract class AbsESF_AssetResponse:IESF_Recycle,IESF_RecycleEventHandler
{
    /// <summary>
    /// 资源路径属性
    /// </summary>
    public ESF_AssetBundlePathAttribute abPathAttr { get; private set; }

    /// <summary>
    /// 信息
    /// </summary>
    public StringBuilder msg{ get; private set; }

    /// <summary>
    /// 错误信息
    /// </summary>
    public StringBuilder error { get; private set; }

    /// <summary>
    /// 进度
    /// </summary>
    public float progress { get; private set; }

    /// <summary>
    /// 场景名称
    /// </summary>
    public string sceneName { get { if (string.IsNullOrEmpty(mSceneName)) { mSceneName = mGetSceneName?.Invoke(abPathAttr); } return mSceneName; } }

    /// <summary>
    /// 是否使用StreamingAssets资源
    /// </summary>
    public bool isUseStreamingAssets { get { return mIsUseStreamingAssets; } }

    /// <summary>
    /// 是否包含在Manifest文件中
    /// </summary>
    public bool isManifestInclude { get { return mIsManifestInclude; } }

    /// <summary>
    /// 资源包完整路径
    /// </summary>
    public string abFullPath { get; private set; }

    /// <summary>
    /// 资源管理器
    /// </summary>
    ESF_ABMgr mAbMgr;

    /// <summary>
    /// 场景名称
    /// </summary>
    string mSceneName = string.Empty;    

    /// <summary>
    /// 获得编辑器资源
    /// </summary>
    System.Func<Object> mGetEditorAsset = null;

    /// <summary>
    /// 获得AssetBundle
    /// </summary>
    System.Func<AssetBundle> mGetAssetBundle = null;

    /// <summary>
    /// 获得场景名称
    /// </summary>
    System.Func<ESF_AssetBundlePathAttribute,string> mGetSceneName = null;

    /// <summary>
    /// 是否使用StreamingAssets资源
    /// </summary>
    bool mIsUseStreamingAssets = false;

    /// <summary>
    /// 是否包含在Manifest文件中
    /// </summary>
    bool mIsManifestInclude = false;

    public event System.Action<IESF_Recycle> OnAfterRecycleHandler;
    public event System.Action<IESF_Recycle> OnBeforeRecycleHandler;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="_abPathAttr">资源属性</param>
    /// <param name="_abMgr">资源管理器</param>
    /// <param name="_onGetEditorAsset">获得编辑器资源</param>
    /// <param name="_onGetAssetBundle">获得AssetBundle</param>
    /// <param name="_onGetSceneName">获得场景名称</param>
    public AbsESF_AssetResponse(ESF_AssetBundlePathAttribute _abPathAttr, ESF_ABMgr _abMgr,System.Func<Object> _onGetEditorAsset,
        System.Func<AssetBundle> _onGetAssetBundle, System.Func<ESF_AssetBundlePathAttribute,string> _onGetSceneName)
    {
        abPathAttr = _abPathAttr;
        mAbMgr = _abMgr;
         mGetEditorAsset = _onGetEditorAsset;
        mGetAssetBundle = _onGetAssetBundle;
        mGetSceneName = _onGetSceneName;
        error = new StringBuilder();
        msg = new StringBuilder();
    }

    /// <summary>
    /// 获得资源路径
    /// </summary>
    /// <returns>资源路径</returns>
    public string GetAssetBundleFullPath()
    {
        abFullPath = mAbMgr.GetAssetBundleFullPath(abPathAttr,out mIsUseStreamingAssets,out mIsManifestInclude);
        return abFullPath;
    }

    /// <summary>
    /// 获得资源依赖项
    /// </summary>
    /// <returns>依赖项</returns>
    public string[] GetAllDependencies()
    {
        return mAbMgr.GetAllDependencies(abPathAttr);
    }

    /// <summary>
    /// 是否有资源
    /// </summary>
    public bool HasAsset()
    {
        bool result = false;
        if (!abPathAttr.isScene)
        {
            switch (mAbMgr.loadModel)
            {
                case enESF_AbLoadModel.Editor:
                    result = mGetEditorAsset() != null;
                    break;
                default:
                    result = mGetAssetBundle() != null;
                    break;
            }
        }
        return result;
    }

    /// <summary>
    /// 获得指定资源
    /// </summary>
    /// <typeparam name="T">资源类型</typeparam>
    /// <returns>指定资源</returns>
    public T GetAsset<T>()
        where T : Object
    {
        T result = default;
        if (!abPathAttr.isScene)
        {
            switch (mAbMgr.loadModel)
            {
                case enESF_AbLoadModel.Editor:
                    if (mGetEditorAsset() != null)
                    {
                        result = OnGetAsset<T>(mGetEditorAsset());
                    }
                    break;
                default:
                    if (mGetAssetBundle() != null)
                    {
                        result = OnGetAsset<T>(mGetAssetBundle().LoadAsset<T>(abPathAttr.assetName));
                    }
                    break;
            }
        }
        return result;
    }

    /// <summary>
    /// 获取指定资源
    /// </summary>
    /// <typeparam name="T">资源类型</typeparam>
    /// <param name="_srcMemoryAsset">源内存资源</param>
    /// <returns>指定资源</returns>
    T OnGetAsset<T>(Object _srcMemoryAsset)
        where T : Object
    {
        T result = null;
        if (_srcMemoryAsset != null)
        {
            if (_srcMemoryAsset is SpriteAtlas
                || _srcMemoryAsset is TextAsset
                || _srcMemoryAsset is Sprite
                || _srcMemoryAsset is Texture)
            {
                result = _srcMemoryAsset as T;
            }
            else
            {
                result = Object.Instantiate(_srcMemoryAsset) as T;
                result.name = _srcMemoryAsset.name;
            }
        }
#if UNITY_EDITOR
        else
        {
            ESF_P.ESF_Error($"未加载资源=>{abPathAttr.assetName}");
        }
#endif
        return result;
    }

    /// <summary>
    /// 添加Msg
    /// </summary>
    /// <param name="_msg">Msg</param>
    public void AddMsg(string _msg)
    {
        msg.AppendLine(_msg);
    }

    /// <summary>
    /// 添加错误信息
    /// </summary>
    /// <param name="_error">错误信息</param>
    public void AddError(string _error)
    {
        error.AppendLine(_error);
    }

    /// <summary>
    /// 设置进度
    /// </summary>
    /// <param name="_progress">进度</param>
    public void SetProgress(float _progress)
    {
        progress = _progress;
    }

    /// <summary>
    /// 清除
    /// </summary>
    public void Recycle()
    {
        OnBeforeRecycleHandler?.Invoke(this);
        OnBeforeRecycleHandler = null;
        error.Length = 0;
        msg.Length = 0;
        OnAfterRecycleHandler?.Invoke(this);
        OnAfterRecycleHandler = null;
    }
}

